#调用pygame库
import pygame
import sys
#调用常用关键字常量
from pygame.locals import QUIT,KEYDOWN
import numpy as np
from environment.GobangCheese import CheeseBoard
from tree.mcts import Mcts,state
from func import end_func, expanded_func, naive_expand_func, naive_value_func
import time
#初始化pygame
pygame.init()
#获取对显示系统的访问，并创建一个窗口screen
#窗口大小为670x670
screen = pygame.display.set_mode((670,670))
screen_color=[238,154,73]#设置画布颜色,[238,154,73]对应为棕黄色
line_color = [0,0,0]#设置线条颜色，[0,0,0]对应黑色
my_board=CheeseBoard()

def mcts_run(board):
    print("ai")
    my_mcts=Mcts(c=1.0, depth_lim=8, end_func=end_func, expanded_func=expanded_func, expand_func=naive_expand_func, value_func=naive_value_func)
    InitState=state(board=board, player=2)
    my_mcts.root(InitState)
    for i in range(5):
        if i%10==0:
            print("hand",i)
        selected_node=my_mcts.select()
        node=my_mcts.expand(selected_node)
        my_mcts.simulation(node)
        my_mcts.backward(node)
    return my_mcts.next()

def find_pos(x,y):#找到显示的可以落子的位置
    s,t=0,0
    for i in range(27,670,44):
        s=s+1
        t=0
        for j in range(27,670,44):
            t=t+1
            L1=i-22
            L2=i+22
            R1=j-22
            R2=j+22
            if x>=L1 and x<=L2 and y>=R1 and y<=R2:
                
                return i,j,s,t
    return x,y,x,y

def check_over_pos(x,y,over_pos):#检查当前的位置是否已经落子
    for val in over_pos:
        if val[0][0]==x and val[0][1]==y:
            return False
    return True#表示没有落子
flag=False
tim=0

over_pos=[]#表示已经落子的位置
white_color=[255,255,255]#白棋颜色
black_color=[0,0,0]#黑棋颜色
tune=0
color=1
renew=False
while True:  # 不断训练刷新画布

    for event in pygame.event.get():  # 获取事件，如果鼠标点击右上角关闭按钮，关闭
        if event.type in (QUIT, KEYDOWN):
            sys.exit()

    screen.fill(screen_color)  # 清屏
    for i in range(27, 670, 44):
        # 先画竖线
        if i == 27 or i == 670 - 27:  # 边缘线稍微粗一些
            pygame.draw.line(screen, line_color, [i, 27], [i, 670 - 27], 4)
        else:
            pygame.draw.line(screen, line_color, [i, 27], [i, 670 - 27], 2)
        # 再画横线
        if i == 27 or i == 670 - 27:  # 边缘线稍微粗一些
            pygame.draw.line(screen, line_color, [27, i], [670 - 27, i], 4)
        else:
            pygame.draw.line(screen, line_color, [27, i], [670 - 27, i], 2)

    # 在棋盘中心画个小圆表示正中心位置
    pygame.draw.circle(screen, line_color, [27 + 44 * 7, 27 + 44 * 7], 8, 0)

    cheeses = my_board.get_putted()
    for val in cheeses:
        pygame.draw.circle(screen, black_color if val[1] == 1 else white_color, [val[0][1] * 44 - 14, val[0][0] * 44 - 14], 20, 0)

    # 判断是否存在五子连心
    res = my_board.check_win()
    if res[0] != 0:
        for pos in res[1]:
            pygame.draw.rect(screen, [238, 48, 167], [pos[1] * 44 - 34, pos[0] * 44 - 34, 44, 44], 2, 1)
        pygame.display.update()  # 刷新显示
        continue  # 游戏结束，停止下面的操作

    # 获取鼠标坐标信息
    if tune == 0:  # 玩家回合
        x, y = pygame.mouse.get_pos()
        x, y, s, t = find_pos(x, y)
        keys_pressed = pygame.mouse.get_pressed()  # 获取鼠标按键信息
    else:  # AI回合
        put = mcts_run(my_board.board)
        x = put[1] * 44 + 27
        y = put[0] * 44 + 27
        x, y, s, t = find_pos(x, y)
        if my_board.putable(t, s):  # 判断是否可以落子
            my_board.put(y=t, x=s, color=2)  # AI落子
            renew = True  # AI执行完毕后，设置renew为True
            color = 1  # 切换回玩家
            tune = 0  # 切换回玩家回合

    try:
        if my_board.putable(t, s):  # 判断是否可以落子，再显示
            pygame.draw.rect(screen, [0, 229, 238], [x - 22, y - 22, 44, 44], 2, 1)
    except:
        continue

    
    # 鼠标左键表示落子,tim用来延时的，因为每次循环时间间隔很断，容易导致明明只按了一次左键，却被多次获取，认为我按了多次
    if keys_pressed[0] and tim == 0:
        #print(my_board.board)
        flag = True
        if my_board.putable(t, s):  # 判断是否可以落子，再落子
            renew = True
            if color == 1:  # 黑子
                my_board.put(y=t, x=s, color=1)
                color = 2  # 切换到AI
                tune = 1  # 切换到AI回合

    # 鼠标左键延时作用
    if flag:
        tim += 1
    if tim % 50 == 0:  # 延时200ms
        flag = False
        tim = 0

    pygame.display.update()  # 刷新显示
    